.text
.globl badcharTable
.type badcharTable, @function

badcharTable:
    endbr64
    pushq %rbp
    movq %rsp, %rbp
    // gcc编译器通常有subq $xxx, %esp这种语句，是为了在push和pop的时候不破坏局部变量
    // 这个在32位汇编中很重要，但是64位不太需要这么搞，因为基本没有push和pop
    // 但如果有，切记需要减一下，流出足够的空间存放局部变量
    pushq %rcx

    // 把参数pattern保存一下
    movq %rdi, -40(%rbp)
    // 把参数table保存一下
    movq %rsi, -48(%rbp)
    call strlen

    // len
    movl %eax, -20(%rbp)

    // 循环变量i
    movq $256, %rcx
.LOOP_INITIAL:
    movq $256, %rax
    subq %rcx, %rax
    movq -48(%rbp), %rdi
    movl -20(%rbp), %ebx
    movl %ebx, (%rdi, %rax, 4)
    loop .LOOP_INITIAL

    // 循环变量i
    movl $0, -8(%rbp)
    jmp .L4
.L5:
    movl -8(%ebp), %eax
    movl %eax, %edx
    // len
    movl -20(%ebp), %eax
    // len - i
    subl %edx, %eax
    subl $1, %eax
    movl %eax, %edx

    // pattern
    movq -40(%rbp), %rcx
    movl -8(%rbp), %eax
    // movzlq %eax, %rax
    addq %rcx, %rax
    movzbl (%rax), %eax
    movsbq %al, %rax
    leaq 0(, %rax, 4), %rcx
    // table
    movq -48(%rbp), %rax
    addq %rcx, %rax
    movl %edx, (%rax)
    addq $1, -8(%rbp)

.L4:
    // len
    movl -20(%rbp), %eax
    subl $1, %eax
    cmpl %eax, -8(%rbp)
    jb .L5
    nop
    nop

    popq %rcx
    leave
    ret

.text
.globl boyerMoore
.type boyerMoore, @function
boyerMoore:
    pushq %rbp
    movq %rsp, %rbp
    pushq %rbx

    // 先对堆栈内存进行一下划分
    // n: -4(%rbp), m:-8(%rbp)
    // badChar: -1032(%rbp)
    // s:-1036(%rbp)
    // j:-1040(%rbp)
    // text:-1048(%rbp)
    // pattern: -1056(%rbp)
    // 先把text存一下
    movq %rdi, -1048(%rbp)
    movq %rsi, -1056(%rbp)

    // 这里省略了一个movq，不用movq了，它本来就在第一个参数
    call strlen
    movl %eax, var_n
    movq %rsi, %rdi
    call strlen
    movl %eax, var_m

    leaq %rsi, var_badChar
    leaq %rdi, var_pattern
    call badcharTable

    movl $0, var_s
    jmp .Compare
.Continue:
    movl var_m, %eax
    subl $1, %eax
    movl %eax, var_j
    jmp .Compare_Inner
.Continue_Inner:
    subl $1, var_j

.Compare_Inner:
    movl var_j, %eax
    cmpl %eax, $0
    jl .Break_Inner
    movl var_s, %eax
    addl var_j, %eax
    movq var_text, %rbx
    // text[s + j]
    movl (%rbx, %eax, 4), %edx
    movl var_j, %eax
    movq var_pattern, %rbx
    // pattern[j]
    movl (%rbx, %eax, 4), %eax
    cmpl %eax, %edx
    jne .Break_Inner
    jmp .Continue_Inner

.Break_Inner:
    movl var_j, %eax
    cmpl %eax, $0
    jl .Return_Inner
    movl var_s, %eax
    addl var_j, %eax
    movq var_text, %rbx
    // text[s + j]暂时存放在eax
    movl 0(%rbx, %eax, 4), %eax
    movq var_badChar, %rbx
    movl (%rbx, %eax, 4), %eax
    movl %eax, %edx
    movl var_j, %eax
    subl %edx, %eax
    cmpl $1, %eax
    jl .ADD_1_Contine
    movl %eax, %edx
    movl var_s, %eax
    addl %edx, %eax
    movl %eax, var_s
    jmp .Compare

.ADD_1_Contine:
    movl var_s, %eax
    addl $1, %eax
    movl %eax, var_s
    jmp .Compare

.Return_Inner:
    movl var_s, %eax
    jmp .Return

.Compare:
    movl var_m, %eax
    subl var_n, %eax
    cmpl %eax, var_s
    jle .Continue
    movl $-1, %eax

.Return:
    popq %rbx
    movq %rbp, %rsp
    popq %rbp
    ret

.text
.globl main
main:
    endbr64
    pushq %rbp
    movq %rsp, %rbp

    movl $0, %eax
    movq %rbp, %rsp
    popq %rbp
    ret